<template>
  <div class="vtext">
    <div class="emoji">
      <i class="icon iconfont icon-biaoqing1" @click="state()" tabindex="1"></i>
      <transition class="showbox">
        <div class="emojibox" ref="emojibox" v-show="flag" @blur="blurState()" tabindex="0">
          <li v-for="(emoji, key) in emojis" :key="key">
            <img
              :src="'/emoji/'+emoji.file"
              :alt="emoji.code"
              :title="emoji.title"
              @click="insertEmoji"
            />
          </li>
        </div>
      </transition>
    </div>
    <!-- <textarea ref="textarea" v-model="content" @keydown.enter="onKeyup"></textarea> -->
    <div
      contenteditable="true"
      ref="textarea"
      class="contenteditable"
      @keydown.enter="onKeyup"
      @blur="editorBlur"
      @paste="editorPaste"
    ></div>
    <div class="send" @click="send()">
      <span>发送(S)</span>
    </div>
    <transition name="appear">
      <div class="warn" v-show="warn">
        <div class="dexcription">不能发送空白信息</div>
      </div>
    </transition>
  </div>
</template>

<script>
import { mapState, mapActions } from "vuex";
export default {
  data() {
    return {
      flag: false,
      warn: false,
      content: "",
      editor: {}
    };
  },
  computed: {
    ...mapState(["emojis"])
  }, // 在进入的时候 聚焦输入框
  mounted() {
    this.$refs.textarea.focus();
  },
  methods: {
    ...mapActions(["sendMessage"]),
    blurState() {
      this.flag = false;
    },
    state() {
      this.flag = true;
      setTimeout(() => this.$refs.emojibox.focus(), 10);
    },
    // 回车控制
    onKeyup(e) {
      if (!e.shiftKey) {
        e.preventDefault();
        this.send();
      }
    },
    // 发送消息
    send() {
      this.content = this.$refs.textarea.innerHTML;
      if (
        this.content
          .replace(/&nbsp;/g, "")
          .replace(/<br>/g, "")
          .trim().length == 0
      ) {
        this.warn = true;
        this.$refs.textarea.innerHTML = "";
        setTimeout(() => this.$refs.textarea.focus(), 3);
        setTimeout(() => {
          this.warn = false;
        }, 1000);
        return;
      }
      // 发送消息
      this.sendMessage(this.content);
      this.$refs.textarea.innerHTML = "";

      /* if (
        this.content
          .replace(/\r\n/g, "")
          .replace(/\n/g, "")
          .replace(/\s/g, "").length == 0
      ) {
        this.warn = true;
        this.content = "";
        setTimeout(() => this.$refs.textarea.focus(), 3);
        setTimeout(() => {
          this.warn = false;
        }, 1000);
      } else {
        // 发送消息
        this.sendMessage(this.content);
        this.content = "";
      } */
    },
    editorBlur() {
      let selection = window.getSelection();
      this.editor.selection = selection;
      this.editor.blurAnchorNode = selection.anchorNode;
      this.editor.blurAnchorOffset = selection.anchorOffset;
    },
    setFocus() {
      this.$refs.textarea.focus();
      if (this.editor.blurAnchorNode) {
        this.editor.selection.setPosition(
          this.editor.blurAnchorNode,
          this.editor.blurAnchorOffset
        );
      }
    },
    insertEmoji(e) {
      this.flag = false;
      this.setFocus();
      let dom = e.target.cloneNode();

      // 添加css样式
      dom.setAttribute(
        "style",
        "vertical-align: middle; width: 24px; height: 24px;"
      );

      let selection = this.editor.selection;
      let anchorNode = selection.anchorNode;
      let anchorOffset = selection.anchorOffset;
      if (selection.isCollapsed) {
        // 插入
        if (anchorNode.nodeName == "#text") {
          // 文本节点
          anchorNode.splitText(anchorOffset);
          anchorNode.after(dom);
        } else {
          if (anchorOffset >= anchorNode.childNodes.length) {
            // 最后节点，插入即可
            anchorNode.appendChild(dom);
          } else {
            // 中间节点
            anchorNode.childNodes[anchorOffset].before(dom);
          }
        }
        // 纠正焦点
        // this.editor.selection.setPosition(dom)
        // 纠正焦点
        let ran = selection.getRangeAt(0);
        ran = ran.cloneRange();
        ran.setStartAfter(dom);
        selection.removeAllRanges();
        selection.addRange(ran);
      }
    },
    editorPaste(e) {
      e.preventDefault(); //阻止默认复制

      let clipboardData = e.clipboardData; //剪贴板对象
      let clipboardDataValue = clipboardData.getData("text/plain"); //获取文字内容，图片会变为alt属性
      clipboardDataValue = this.toImg(clipboardDataValue); //表情转换为DOMString
      let tempDiv = document.createElement("div"); //容器
      tempDiv.innerHTML = clipboardDataValue; //转换为DOM
      let documentFragment = document.createDocumentFragment();
      let _focus = tempDiv.childNodes[tempDiv.childNodes.length - 1];
      while (tempDiv.childNodes.length) {
        documentFragment.appendChild(tempDiv.childNodes[0]);
      }
      // 获取选区
      let selection = window.getSelection && window.getSelection();
      // 有选区，删除选区内容
      if (
        selection.anchorNode != selection.extentNode ||
        selection.anchorOffset != selection.extentOffset
      ) {
        selection.deleteFromDocument();
      }
      let anchorNode = selection.anchorNode;
      let anchorOffset = selection.anchorOffset;
      if (anchorNode.nodeType == 3) {
        // 在文字节点当中
        anchorNode.splitText(anchorOffset); //分为两个串
        selection.anchorNode.after(documentFragment); //复制
      } else if (anchorNode.nodeType == 1) {
        // 块节点当中
        selection.anchorNode.insertBefore(
          documentFragment,
          anchorNode.childNodes[anchorOffset]
        );
      }
      //设置焦点
      let ran = selection.getRangeAt(0);
      ran = ran.cloneRange();
      ran.setStartAfter(_focus);
      selection.removeAllRanges();
      selection.addRange(ran);
      // pn.focus();
    },
    // 转换特殊字符
    toHtml(val) {
      var entityMap = {
        "&": "&amp;",
        "<": "&lt;",
        ">": "&gt;",
        '"': "&quot;",
        "'": "&#39;",
        "/": "&#x2F;"
      };
      return String(val).replace(/[&<>"'/]/g, function(s) {
        return entityMap[s];
      });
    },
    // 转换表情
    toImg(val) {
      if (val.includes("/:")) {
        let emojis = this.emojis;
        for (let i in emojis) {
          val = val.replace(
            emojis[i].reg,
            '<img src="/emoji/' +
              emojis[i].file +
              '"  alt="' +
              emojis[i].code +
              '" style="vertical-align: middle; width: 24px; height: 24px;"/>'
          );
        }
      }
      return val;
    }
  }
};
</script>

<style scoped>
.vtext {
  position: relative;
  height: 150px;
  /* background-color: #fff; */
  background-color: #f2f2f2;
  outline: none;
}

.vtext:focus-within {
  background-color: #fff;
}

.emoji {
  position: relative;
  width: 100%;
  height: 35px;
  line-height: 40px;
  font-size: 12px;
  padding: 0 30px;
  box-sizing: border-box;
  color: #878787;
  outline: none;
}

.emoji .icon-biaoqing1 {
  font-size: 18px;
  cursor: pointer;
  outline: none;
}

.emoji .icon-biaoqing1:hover {
  color: #1aad19;
}

.emoji .emojibox {
  position: absolute;
  display: flex;
  flex-wrap: wrap;
  top: -210px;
  left: -100px;
  width: 300px;
  height: 200px;
  padding: 5px;
  background-color: #fff;
  border: 1px solid #d1d1d1;
  border-radius: 2px;
  box-shadow: 0 1px 2px 1px #d1d1d1;
  outline: none;
}

.emoji .emojiBox .showbox-enter-active,
.emoji .emojiBox .showbox-leave-active {
  transition: all 0.5s;
}

.emoji .emojiBox .showbox-enter,
.emoji .emojiBox .showbox-leave-active {
  opacity: 0;
}

textarea {
  box-sizing: border-box;
  padding: 0 30px;
  height: 100px;
  width: 100%;
  border: none;
  outline: none;
  font-family: "Micrsofot Yahei";
  resize: none;
  background-color: transparent;
}

.contenteditable {
  box-sizing: border-box;
  height: 75px;
  width: 500px;
  line-height: 20px;
  margin: 3px auto;
  font-size: 14px;
  font-family: "Micrsofot Yahei";
  background-color: transparent;
  overflow-y: scroll;
  outline: none;
}

textarea:focus {
  background-color: #fff;
}

.send {
  position: absolute;
  bottom: 10px;
  right: 30px;
  width: 75px;
  height: 28px;
  line-height: 28px;
  box-sizing: border-box;
  text-align: center;
  border: 1px solid #e5e5e5;
  border-radius: 3px;
  background: #f5f5f5;
  font-size: 14px;
  color: #7c7c7c;
  cursor: pointer;
}

.send:hover {
  background: rgb(18, 150, 17);
  color: #fff;
}

.warn {
  position: absolute;
  bottom: 50px;
  right: 10px;
  width: 110px;
  height: 30px;
  line-height: 30px;
  font-size: 12px;
  text-align: center;
  border: 1px solid #bdbdbd;
  border-radius: 4px;
  box-shadow: 0 1px 5px 1px #bdbdbd;
}

.warn .appear-enter-active,
.warn .appear-leave-active {
  transition: all 1s;
}

.warn .appear-enter,
.warn .appear-leave-active {
  opacity: 0;
}

.warn:before {
  content: " ";
  position: absolute;
  top: 100%;
  right: 20px;
  border: 7px solid transparent;
  border-top-color: #fff;
  filter: drop-shadow(1px 3px 2px #bdbdbd);
}
</style>